﻿/*
 * 2021.03.27-Code rectification and function enhancement.
 *            Huawei Device Co., Ltd. <mobile@huawei.com>
 */

#ifndef __UIRICHEDIT_H__
#define __UIRICHEDIT_H__

#pragma once
#include <Imm.h>
#pragma comment(lib, "imm32.lib")

namespace DuiLib {
class CTxtWinHost;

class UILIB_API CRichEditUI : public CContainerUI, public IMessageFilterUI {
    DECLARE_DUICONTROL(CRichEditUI)
public:
    CRichEditUI();
    ~CRichEditUI();

    LPCTSTR GetClass() const;
    LPVOID GetInterface(LPCTSTR pstrName);
    UINT GetControlFlags() const;

    bool IsMultiLine();
    void SetMultiLine(bool bMultiLine);
    bool IsWantTab();
    void SetWantTab(bool bWantTab = true);
    bool IsWantReturn();
    void SetWantReturn(bool bWantReturn = true);
    bool IsWantCtrlReturn();
    void SetWantCtrlReturn(bool bWantCtrlReturn = true);
    bool IsRich();
    void SetRich(bool bRich = true);
    bool IsReadOnly();
    void SetReadOnly(bool bReadOnly = true);
    bool GetWordWrap();
    void SetWordWrap(bool bWordWrap = true);
    int GetFont();
    void SetFont(int index);
    void SetFont(LPCTSTR pStrFontName, int nSize, bool bBold, bool bUnderline, bool bItalic);
    void SetEnabled(bool bEnabled) override;
    LONG GetWinStyle();
    void SetWinStyle(LONG lStyle);
    DWORD GetTextColor();
    void SetTextColor(DWORD dwTextColor);
    int GetLimitText();
    void SetLimitText(int iChars);
    long GetTextLength(DWORD dwFlags = GTL_DEFAULT) const;
    CDuiString GetText() const override;
    void SetText(LPCTSTR pstrText);
    bool GetModify() const;
    void SetModify(bool bModified = true) const;
    void GetSel(CHARRANGE &cr) const;
    void GetSel(long &nStartChar, long &nEndChar) const;
    int SetSel(CHARRANGE &cr);
    int SetSel(long nStartChar, long nEndChar);
    void ReplaceSel(LPCTSTR lpszNewText, bool bCanUndo);
    void ReplaceSelW(LPCWSTR lpszNewText, bool bCanUndo = false);
    CDuiString GetSelText() const;
    int SetSelAll();
    int SetSelNone();
    void SetDefaultAlign(WORD wNewAlign);
    WORD GetSelectionType() const;
    bool GetZoom(int &nNum, int &nDen) const;
    bool SetZoom(int nNum, int nDen);
    bool SetZoomOff();
    bool GetAutoURLDetect() const;
    bool SetAutoURLDetect(bool bAutoDetect = true);
    DWORD GetEventMask() const;
    DWORD SetEventMask(DWORD dwEventMask);
    CDuiString GetTextRange(long nStartChar, long nEndChar) const;
    void HideSelection(bool bHide = true, bool bChangeStyle = false);
    void ScrollCaret();
    int InsertText(long nInsertAfterChar, LPCTSTR lpstrText, bool bCanUndo = false);
    int AppendText(LPCTSTR lpstrText, bool bCanUndo = false);
    DWORD GetDefaultCharFormat(CHARFORMAT2 &cf) const;
    bool SetDefaultCharFormat(CHARFORMAT2 &cf);
    DWORD GetSelectionCharFormat(CHARFORMAT2 &cf) const;
    bool SetSelectionCharFormat(CHARFORMAT2 &cf);
    bool SetWordCharFormat(CHARFORMAT2 &cf);
    DWORD GetParaFormat(PARAFORMAT2 &pf) const;
    bool SetParaFormat(PARAFORMAT2 &pf);
    bool Redo();
    bool Undo();
    void Clear();
    void Copy();
    void Cut();
    void Paste();
    int GetLineCount() const;
    CDuiString GetLine(int nIndex, int nMaxLength) const;
    int LineIndex(int nLine = -1) const;
    int LineLength(int nLine = -1) const;
    bool LineScroll(int nLines, int nChars = 0);
    CDuiPoint GetCharPos(long lChar) const;
    long LineFromChar(long nIndex) const;
    CDuiPoint PosFromChar(UINT nChar) const;
    int CharFromPos(CDuiPoint pt) const;
    void EmptyUndoBuffer();
    UINT SetUndoLimit(UINT nLimit);
    long StreamIn(int nFormat, EDITSTREAM &es);
    long StreamOut(int nFormat, EDITSTREAM &es);
    void SetAccumulateDBCMode(bool bDBCMode);
    bool IsAccumulateDBCMode();

    void DoInit() override;
    // 注意：TxSendMessage和SendMessage是有区别的，TxSendMessage没有multibyte和unicode自动转换的功能，
    // 而richedit2.0内部是以unicode实现的，在multibyte程序中，必须自己处理unicode到multibyte的转换
    bool SetDropAcceptFile(bool bAccept);
    virtual HRESULT TxSendMessage(UINT msg, WPARAM wparam, LPARAM lparam, LRESULT *plresult) const;
    IDropTarget *GetTxDropTarget();
    virtual bool OnTxViewChanged(BOOL bUpdate);
    virtual void OnTxNotify(DWORD iNotify, void *pv);

    void SetScrollPos(SIZE szPos, bool bMsg = true);
    void LineUp() override;
    void LineDown() override;
    void PageUp() override;
    void PageDown() override;
    void HomeUp() override;
    void EndDown() override;
    void LineLeft() override;
    void LineRight() override;
    void PageLeft() override;
    void PageRight() override;
    void HomeLeft() override;
    void EndRight() override;

    SIZE EstimateSize(SIZE szAvailable);
    void SetPos(RECT rc, bool bNeedInvalidate = true);
    void Move(SIZE szOffset, bool bNeedInvalidate = true);
    void DoEvent(TEventUI &event) override;
    void DoPaint(HDC hDC, const RECT &rcPaint);

    LPCTSTR GetNormalImage();
    void SetNormalImage(LPCTSTR pStrImage);
    LPCTSTR GetHotImage();
    void SetHotImage(LPCTSTR pStrImage);
    LPCTSTR GetFocusedImage();
    void SetFocusedImage(LPCTSTR pStrImage);
    LPCTSTR GetDisabledImage();
    void SetDisabledImage(LPCTSTR pStrImage);
    void PaintStatusImage(HDC hDC);
    RECT GetTextPadding() const;
    void SetTextPadding(RECT rc);

    void SetTipValue(LPCTSTR pStrTipValue);
    LPCTSTR GetTipValue();
    void SetTipValueColor(LPCTSTR pStrColor);
    DWORD GetTipValueColor();
    void SetTipValueAlign(UINT uAlign);
    UINT GetTipValueAlign();

    void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);
    void JudgeDirection(LPCTSTR pstrValue);
    void JudgeTipDirection(LPCTSTR pstrValue);
    LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, bool &bHandled);

protected:
    CTxtWinHost *m_pTwh;
    bool m_bVScrollBarFixing;
    bool m_bWantTab;
    bool m_bWantReturn;
    bool m_bWantCtrlReturn;
    bool m_bRich;
    bool m_bReadOnly;
    bool m_bWordWrap;
    DWORD m_dwTextColor;
    int m_iFont;
    int m_iLimitText;
    ULONG m_lTwhStyle;
    bool m_bDrawCaret;
    bool m_bInited;
    bool m_fAccumulateDBC; // TRUE - need to cumulate ytes from 2 WM_CHAR msgs
    // we are in this mode when we receive VK_PROCESSKEY
    UINT m_chLeadByte; // use when we are in _fAccumulateDBC mode

    UINT m_uButtonState;
    CDuiString m_sNormalImage;
    CDuiString m_sHotImage;
    CDuiString m_sFocusedImage;
    CDuiString m_sDisabledImage;
    RECT m_rcTextPadding;
    DWORD m_dwTipValueColor;
    UINT m_uTipValueAlign;
};
} // namespace DuiLib

#endif // __UIRICHEDIT_H__
